package com.aboo.es.service;

import com.aboo.es.vo.Actor;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ActorService {

    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    public void createIndex() {
        // 创建索引，会根据Item类的@Document注解信息来创建
        elasticsearchTemplate.createIndex(Actor.class);
        // 配置映射，会根据Item类中的id、Field等字段来自动完成映射
        elasticsearchTemplate.putMapping(Actor.class);
    }

    public void saveOne(Actor actor) {
        if (actor == null || StringUtils.isBlank(actor.getActorCode())) {
            return;
        }

        actor.setCreatedDate(new Date());
        IndexQuery indexQuery = new IndexQueryBuilder()
                .withId(actor.getActorCode())
                .withObject(actor)
                .build();
        elasticsearchTemplate.index(indexQuery);
    }

    public void saveMore(List<Actor> actors) {
        if (actors == null || CollectionUtils.isEmpty(actors)) {
            return;
        }

        List<IndexQuery> indexQueryList = new ArrayList<>(16);
        int size = actors.size();
        for (int i = 0; i < size; i++) {
            actors.get(i).setCreatedDate(new Date());
            IndexQuery indexQuery = new IndexQueryBuilder()
                    .withId(actors.get(i).getActorCode())
                    .withObject(actors.get(i))
                    .build();
            indexQueryList.add(indexQuery);

            if ((i % 10 == 0 && i != 0) || i == (size - 1)) {
                elasticsearchTemplate.bulkIndex(indexQueryList);
                indexQueryList.clear();
            }
        }
    }

    public Page<Actor> queryPage(String queryStr, int page, int size, Sort.Direction direction, String field) {
        if (StringUtils.isBlank(queryStr)) {
            return null;
        }
        if (page < 0) {
            page = 0;
        }
        if (size <= 0) {
            page = 20;
        }

        Sort sort = null;
        if (direction != null && StringUtils.isNotBlank(field)) {
            sort = Sort.by(direction, field);
        }
        Pageable pageable = PageRequest.of(page, size, sort);

        QueryBuilder queryBuilder = null;
        // 模糊查询
        queryBuilder = QueryBuilders.queryStringQuery(queryStr);
        // 模糊查询
//        queryBuilder = QueryBuilders.matchQuery("desc", queryStr);
        // 其余匹配
//        queryBuilder = QueryBuilders.matchPhraseQuery("desc", queryStr);
        // 全等查询
//        queryBuilder = QueryBuilders.termQuery("desc", queryStr);

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices("actor")
                .withQuery(queryBuilder)
                .withPageable(pageable)
                .build();

        Page<Actor> pageResult = elasticsearchTemplate.queryForPage(searchQuery, Actor.class);
        return pageResult;
    }

    public Page<Actor> queryPage(Map<String, String> queryMap, int page, int size, Sort.Direction direction, String field) {
        if (CollectionUtils.isEmpty(queryMap)) {
            return null;
        }
        if (page < 0) {
            page = 0;
        }
        if (size <= 0) {
            page = 20;
        }

        Sort sort = null;
        if (direction != null && StringUtils.isNotBlank(field)) {
            sort = Sort.by(direction, field);
        }
        Pageable pageable = PageRequest.of(page, size, sort);

        // 组合查询
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryMap.forEach((a, b) -> {
            queryBuilder.filter(QueryBuilders.matchPhraseQuery(a, b));
        });

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices("actor")
                .withQuery(queryBuilder)
                .withPageable(pageable)
                .build();

        Page<Actor> pageResult = elasticsearchTemplate.queryForPage(searchQuery, Actor.class);
        return pageResult;
    }

}
